package com.woniuxy.project115.kaer.tenant.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.project115.kaer.tenant.entity.Appointment;
import com.woniuxy.project115.kaer.tenant.entity.AppointmentItem;
import com.woniuxy.project115.kaer.tenant.entity.ProcessLog;
import com.woniuxy.project115.kaer.tenant.entity.ServiceOrder;
import com.woniuxy.project115.kaer.tenant.mapper.AppointmentItemMapper;
import com.woniuxy.project115.kaer.tenant.mapper.AppointmentMapper;
import com.woniuxy.project115.kaer.tenant.mapper.ProcessLogMapper;
import com.woniuxy.project115.kaer.tenant.mapper.ServiceOrderMapper;
import com.woniuxy.project115.kaer.tenant.param.AppointmentItemParam;
import com.woniuxy.project115.kaer.tenant.service.AppointmentItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.project115.kaer.tenant.util.Data;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author HuH
 * @since 2025年02月18日
 */
@Service
public class AppointmentItemServiceImpl extends ServiceImpl<AppointmentItemMapper, AppointmentItem> implements AppointmentItemService {
    @Resource
    private AppointmentItemMapper appointmentItemMapper;

    @Resource
    private AppointmentMapper appointmentMapper;

    @Resource
    private ServiceOrderMapper serviceOrderMapper;

    @Resource
    private ProcessLogMapper processLogMapper;

    /**
     * 修改预约项目信息
     * @param param 包含预约项目信息的参数对象
     * @throws Exception 如果预约项目不存在或已确认，则抛出异常
     */
    @Override
    public void modifyAppointmentItem(AppointmentItemParam param) throws Exception {
        AppointmentItem appointmentItem = appointmentItemMapper.selectById(param.getItemId());
        if (appointmentItem == null) {
            throw new Exception("预约项目不存在");
        }
        if (appointmentItem.getState() == Data.APPOINTMENT_ITEM_CONFIRMED) {
            throw new Exception("预约项目已确认，无法修改");
        }
        appointmentItemMapper.updateById(BeanUtil.toBean(param, AppointmentItem.class));
        updateTotalPrice(appointmentItem.getAppointmentId());
    }

    /**
     * 添加预约项目
     * @param param 包含预约项目信息的参数对象
     * @throws Exception 如果预约项目已确认，则抛出异常
     */
    @Override
    public void addAppointmentItem(AppointmentItemParam param) throws Exception {
        List<AppointmentItem> list = appointmentItemMapper.selectList(new QueryWrapper<AppointmentItem>().eq("appointment_id", param.getAppointmentId()));
        AppointmentItem appointmentItem = list.get(0);
        if (appointmentItem.getState() == Data.APPOINTMENT_ITEM_CONFIRMED) {
            throw new Exception("预约项目已确认，无法修改");
        }
        appointmentItemMapper.insert(BeanUtil.toBean(param, AppointmentItem.class));
        updateTotalPrice(appointmentItem.getAppointmentId());
    }

    /**
     * 删除预约项目
     * @param itemId 预约项目的ID
     * @throws Exception 如果预约项目不存在或已确认，则抛出异常
     */
    @Override
    public void removeAppointmentItem(Integer itemId) throws Exception {
        AppointmentItem appointmentItem = appointmentItemMapper.selectById(itemId);
        if (appointmentItem == null) {
            throw new Exception("预约项目不存在");
        }
        if (appointmentItem.getState() == Data.APPOINTMENT_ITEM_CONFIRMED) {
            throw new Exception("预约项目已确认，无法删除");
        }
        Integer appointmentId = appointmentItem.getAppointmentId();
        appointmentItemMapper.deleteById(itemId);
        updateTotalPrice(appointmentId);
    }

    /**
     * 开始服务项目
     * @param itemId 预约项目的ID
     * @param operator 操作员名称
     * @throws Exception 如果预约项目不存在或状态异常，则抛出异常
     */
    @Override
    public void startServiceItem(Integer itemId, String operator) throws Exception {
        AppointmentItem item = appointmentItemMapper.selectById(itemId);
        if (item == null) {
            throw new Exception("预约项目不存在");
        }
        if (item.getState() != Data.APPOINTMENT_ITEM_CONFIRMED) {
            throw new Exception("预约项目状态异常");
        }

        ServiceOrder serviceOrder = serviceOrderMapper.selectOne(new QueryWrapper<ServiceOrder>().eq("appointment_id", item.getAppointmentId()));
        if (serviceOrder.getState() == Data.SERVICE_ORDER_WAIT_SERVICE) {//如果订单状态为待服务
            serviceOrder.setState(Data.SERVICE_ORDER_SERVICING);//修改订单状态为服务中
        }
        serviceOrder.setServiceNodeId(itemId);//更改正在服务中的节点id
        serviceOrderMapper.updateById(serviceOrder);

        //修改服务项目信息 状态
        item.setState(Data.APPOINTMENT_ITEM_SERVICING)
                .setStartTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                .setEmployeeName(operator);
        appointmentItemMapper.updateById(item);

        //新增服务进度日志
        ProcessLog processLog = new ProcessLog();
        processLog.setServiceOrderNum(serviceOrder.getServiceOrderNum())
                .setItemId(itemId)
                .setOperator(operator)
                .setOperateTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                .setOperateType("开始服务");
        processLogMapper.insert(processLog);
    }

    /**
     * 结束服务项目
     * @param itemId 预约项目的ID
     * @param operator 操作员名称
     * @throws Exception 如果预约项目不存在或状态异常，则抛出异常
     */
    @Override
    public void endServiceItem(Integer itemId, String operator) throws Exception {
        AppointmentItem item = appointmentItemMapper.selectById(itemId);
        if (item == null) {
            throw new Exception("预约项目不存在");
        }
        if (item.getState() != Data.APPOINTMENT_ITEM_SERVICING) {
            throw new Exception("预约项目状态异常");
        }

        //修改服务项目信息 状态
        item.setState(Data.APPOINTMENT_ITEM_SERVICED)
                .setEndTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                .setEmployeeName(operator);
        appointmentItemMapper.updateById(item);

        //更新服务进度日志
        ProcessLog processLog = new ProcessLog();
        processLog.setServiceOrderNum(serviceOrderMapper.selectOne(new QueryWrapper<ServiceOrder>().eq("appointment_id", item.getAppointmentId())).getServiceOrderNum())
                .setItemId(itemId)
                .setOperator(operator)
                .setOperateTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                .setOperateType("完成服务");
        processLogMapper.insert(processLog);
    }

    @Override
    public List<AppointmentItem> getAppointmentItem(Integer appointmentId) throws Exception {
        List<AppointmentItem> list = appointmentItemMapper.selectList(
                new QueryWrapper<AppointmentItem>()
                        .eq("appointment_id", appointmentId));

        return list;
    }

    /**
     * 更新服务总价格
     * @param appointmentId 预约ID
     */
    private void updateTotalPrice(Integer appointmentId) {
        List<AppointmentItem> list = appointmentItemMapper.selectList(new QueryWrapper<AppointmentItem>().eq("appointment_id", appointmentId));
        Double totalPrice = 0.0;
        for (AppointmentItem appointmentItem : list) {
            totalPrice += appointmentItem.getUnitPrice() * appointmentItem.getNumber() + appointmentItem.getLaborCost();
        }
        Appointment appointment = appointmentMapper.selectById(appointmentId);
        appointmentMapper.updateById(appointment.setTotalPrice(totalPrice));
    }
}